package com.leyu.mall.site.search.controller;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.leyu.mall.site.base.controller.HeaderController;
import com.leyu.search.service.GoodsSearchService;
import com.leyu.search.service.SearchQueryParam;
import com.leyu.search.service.SearchResult;
import com.leyu.search.service.SearchResult.ItemCounter;

/**
 * @author change
 * 
 */
@Controller
@RequestMapping(value = "/search")
public class SearchController extends HeaderController{
	@Resource
	private GoodsSearchService goodsSearchService;
	private static final CategoryView defaultCateView = new CategoryView();
	String[] facetFields = new String[] { "areaId", "brandId", "priceRangeId",
			"systemId", "screenSizeId", "specialId" };
	 
	@RequestMapping(method = { RequestMethod.GET, RequestMethod.POST })
	public String search(SearchForm form, Model model,
			HttpServletRequest request) {
		SearchQueryParam param = this.buildQueryParam(form);
		SearchResult result = goodsSearchService.search(param);
		model.addAttribute("searchResult", result);
		model.addAttribute("keywords", form.q);
		CategoryView cateView = this.buildCategoryView(result, param);
		model.addAttribute("cateView", cateView);
		String queryString = request.getQueryString();
		if (StringUtils.isNotBlank(queryString)) {
			String keyValuePairs[] = queryString.split("&");
			String pname = null, value = null;
			for (int i = 0; i < keyValuePairs.length; i++) {
				String keyValuePair = keyValuePairs[i];
				String kvArr[] = keyValuePair.split("=");
				if (kvArr.length != 2)
					continue;
				IdText selected = defaultCateView.selected(kvArr[0], kvArr[1]);
				if (selected != null) {
					selected.pname = kvArr[0];
					selected.href = "#";
					cateView.selecteds.add(selected);
				}
			}
		}
		return "search/main_search.html";
	}

	private CategoryView buildCategoryView(SearchResult result,
			SearchQueryParam param) {
		CategoryView cateView = createCategoryView();
		final String arrays[] = new String[SearchQueryParam.ARRAY_SIZE];
		final String srcArrays[] = param.getParamsArray();
		System.arraycopy(srcArrays, 0, arrays, 0, srcArrays.length);
		for (int i = 0; i < cateView.cateArrays.length; i++) {
			Set<IdText> idTextDatas = (Set<IdText>) cateView.cateArrays[i];
			this.initCateView(arrays, 3 + i, idTextDatas);
			this.filterCateView(result.cateCountersMap.get(facetFields[i]),
					idTextDatas);
		}
		this.initCateView(arrays, 9, cateView.sorts);
		if (param.areaId != null && param.areaId != 0) {
			cateView.areas.clear();
		}
		if (param.brandId != null && param.brandId != 0) {
			cateView.brands.clear();
		}
		if (param.priceRangeId != null && param.priceRangeId != 0) {
			cateView.priceRanges.clear();
		}
		if (param.systemId != null && param.systemId != 0) {
			cateView.systems.clear();
		}
		if (param.screenSizeId != null && param.screenSizeId != 0) {
			cateView.screens.clear();
		}
		if (param.specialId != null && param.specialId != 0) {
			cateView.specials.clear();
		}
		return cateView;
	}

	private void initCateView(String arrays[], int index, Set<IdText> idText) {
		String t = arrays[index];
		for (IdText item : idText) {
			arrays[index] = item.id + "";
			if (arrays[index].equals(t)) {
				item.selected = true;
			}
			item.href = "#";
		}
		arrays[index] = t;
	}

	private void filterCateView(List<ItemCounter> counters,
			Set<IdText> idTextSet) {
		if (idTextSet == null || idTextSet.isEmpty())
			return;
		Map<Long, IdText> map = new LinkedHashMap<Long, IdText>();
		for (IdText item : idTextSet) {
			map.put(item.id, item);
		}
		for (ItemCounter counter : counters) {
			IdText item = map.get(counter.getId());
			if (item == null) {
				continue;
			}
			if (counter.getCount() == null || counter.getCount() <= 0) {
				idTextSet.remove(item);
			} else {
				item.count = counter.getCount();
			}
		}
		if (idTextSet.size() == 1 && idTextSet.iterator().next().id.equals(0L)) {
			idTextSet.clear();
		}

	}

	public CategoryView createCategoryView() {
		IdText areas[] = { idText(1, "北京"), idText(2, "上海"), idText(3, "广州"),
				idText(4, "深圳") };
		for (IdText item : areas) {
			defaultCateView.areas.add(item);
		}
		IdText brands[] = { idText(11, "APPLE"), idText(12, "NOKIA"),
				idText(13, "SANSUNG"), idText(14, "SONY"), idText(15, "HTC"),
				idText(16, "HUAWEI"), idText(17, "ZTE"), idText(18, "COOLPAD"),
				idText(19, "LENOVO") };
		for (IdText item : brands) {
			defaultCateView.brands.add(item);
		}
		IdText priceRanges[] = { idText(41, "1-999"), idText(42, "1000-1999"),
				idText(43, "1999-2999"), idText(44, "3000-4999"),
				idText(45, "5000以上") };
		for (IdText item : priceRanges) {
			defaultCateView.priceRanges.add(item);
		}
		IdText systems[] = { idText(21, "IOS"), idText(22, "ANDRIOD"),
				idText(23, "WINDOWSPHONE"), idText(24, "WINDOSMOBILE"),
				idText(25, "SYMBIAN") };
		for (IdText item : systems) {
			defaultCateView.systems.add(item);
		}
		IdText screens[] = { idText(31, "2.7英寸及一下"), idText(32, "2.8-3.4英寸"),
				idText(33, "3.5-4.0英寸"), idText(34, "4.3英寸及以上的屏幕") };
		for (IdText item : screens) {
			defaultCateView.screens.add(item);
		}
		IdText specialTags[] = { idText(31, "双核"), idText(32, "3G视频通话"),
				idText(33, "wifi/wapi"), idText(34, "高像素手机"),
				idText(35, "导航手机"), idText(36, "商务手机"), idText(37, "女性手机"),
				idText(38, "手机电视") };
		for (IdText item : specialTags) {
			defaultCateView.specials.add(item);
		}
		IdText sorts[] = { idText(1, "销量"), idText(2, "价格"), idText(3, "评论数"),
				idText(4, "上架时间") };
		for (IdText item : sorts) {
			defaultCateView.sorts.add(item);
		}
		CategoryView cateView = defaultCateView.clone();
		return cateView;
	}

	public IdText idText(int id, String text) {
		IdText t = new IdText();
		t.id = Long.valueOf(id);
		t.text = text;
		return t;
	}

	private SearchQueryParam buildQueryParam(SearchForm form) {
		SearchQueryParam param = new SearchQueryParam();
		param.keywords = form.q;
		String paramsArray[] = new String[SearchQueryParam.ARRAY_SIZE];
		paramsArray[0] = "0";
		paramsArray[1] = "0";
		paramsArray[2] = "0";
		paramsArray[3] = form.area;
		paramsArray[4] = form.brand;
		paramsArray[5] = form.price;
		paramsArray[6] = form.os;
		paramsArray[7] = form.screen;
		paramsArray[8] = form.sp;
		paramsArray[9] = form.sort;
		paramsArray[10] = "0";
		paramsArray[11] = "0";
		paramsArray[12] = form.pageNo + "";
		param.setParamsArray(paramsArray);
		param.facetQuery = true;
		param.onlyKeywords = form.isOnlyKeywordQuery();
		return param;
	}

	public static class SearchForm {
		private String q;
		private String area;
		private String brand;
		private String price;
		private String os;
		private String screen;
		private String sp;
		private String sort = "1";
		private Integer pageNo;
		private Integer pageSize = 40;

		public boolean isOnlyKeywordQuery() {
			String arrays[] = { area, brand, price, os, screen, sp };
			for (String item : arrays) {
				if (StringUtils.isNotBlank(item)) {
					return false;
				}
			}
			return true;
		}

		public String getSp() {
			return sp;
		}

		public void setSp(String sp) {
			this.sp = sp;
		}

		public Integer getPageNo() {
			return pageNo;
		}

		public void setPageNo(Integer pageNo) {
			this.pageNo = pageNo;
		}

		public Integer getPageSize() {
			return pageSize;
		}

		public void setPageSize(Integer pageSize) {
			this.pageSize = pageSize;
		}

		public String getQ() {
			return q;
		}

		public void setQ(String q) {
			this.q = q;
		}

		public String getArea() {
			return area;
		}

		public void setArea(String area) {
			this.area = area;
		}

		public String getBrand() {
			return brand;
		}

		public void setBrand(String brand) {
			this.brand = brand;
		}

		public String getPrice() {
			return price;
		}

		public void setPrice(String price) {
			this.price = price;
		}

		public String getOs() {
			return os;
		}

		public void setOs(String os) {
			this.os = os;
		}

		public String getScreen() {
			return screen;
		}

		public void setScreen(String screen) {
			this.screen = screen;
		}

		public String getSort() {
			return sort;
		}

		public void setSort(String sort) {
			this.sort = sort;
		}

	}

}
